'use strict';

var is = require('bpmn-js/lib/util/ModelUtil').is;

var entryFactory = require('../../../../factory/EntryFactory');

var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper');

var elementHelper = require('bpmn-js-properties-panel/lib/helper/ElementHelper'),
    eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'),
    cmdHelper = require('../../../../helper/CmdHelper');

function isAsyncBefore(bo) {
    return asyncCapableHelper.isAsyncBefore(bo);
}

function isAsyncAfter(bo) {
    return asyncCapableHelper.isAsyncAfter(bo);
}

function getFailedJobRetryTimeCycle(bo) {
    return asyncCapableHelper.getFailedJobRetryTimeCycle(bo);
}

function removeFailedJobRetryTimeCycle(bo, element) {
    return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element);
}

function createExtensionElements(parent, bpmnFactory) {
    return elementHelper.createElement('bpmn:ExtensionElements', {values: []}, parent, bpmnFactory);
}

function createFailedJobRetryTimeCycle(parent, bpmnFactory, cycle) {
    return elementHelper.createElement('flowable:FailedJobRetryTimeCycle', {body: cycle}, parent, bpmnFactory);
}

module.exports = function (element, bpmnFactory, options, translate) {

    var getBusinessObject = options.getBusinessObject;

    var idPrefix = options.idPrefix || '',
        labelPrefix = options.labelPrefix || '';

    var retryTimeCycleEntry = entryFactory.textField({
        id: idPrefix + 'retryTimeCycle',
        label: labelPrefix + translate('Retry Time Cycle'),
        modelProperty: 'cycle',

        get: function (element, node) {
            var retryTimeCycle = getFailedJobRetryTimeCycle(getBusinessObject(element));
            var value = retryTimeCycle && retryTimeCycle.get('body');
            return {
                cycle: value
            };
        },

        set: function (element, values, node) {
            var newCycle = values.cycle;
            var bo = getBusinessObject(element);

            if (newCycle === '' || typeof newCycle === 'undefined') {
                // remove retry time cycle element(s)
                return removeFailedJobRetryTimeCycle(bo, element);
            }

            var retryTimeCycle = getFailedJobRetryTimeCycle(bo);

            if (!retryTimeCycle) {
                // add new retry time cycle element
                var commands = [];

                var extensionElements = bo.get('extensionElements');
                if (!extensionElements) {
                    extensionElements = createExtensionElements(bo, bpmnFactory);
                    commands.push(cmdHelper.updateBusinessObject(element, bo, {extensionElements: extensionElements}));
                }

                retryTimeCycle = createFailedJobRetryTimeCycle(extensionElements, bpmnFactory, newCycle);
                commands.push(cmdHelper.addAndRemoveElementsFromList(
                    element,
                    extensionElements,
                    'values',
                    'extensionElements',
                    [retryTimeCycle],
                    []
                ));

                return commands;
            }

            // update existing retry time cycle element
            return cmdHelper.updateBusinessObject(element, retryTimeCycle, {body: newCycle});
        },

        hidden: function (element) {
            var bo = getBusinessObject(element);

            if (bo && (isAsyncBefore(bo) || isAsyncAfter(bo))) {
                return false;
            }

            if (is(element, 'bpmn:Event')) {
                return !eventDefinitionHelper.getTimerEventDefinition(element);
            }

            return true;
        }

    });

    return [retryTimeCycleEntry];

};
